﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Wpf2.Models;
using Wpf2.Views;
using WPFServices;

namespace Wpf2.ViewModels
{
    /// <summary>
    /// Class ViewModel dành cho form [cập nhật Hóa Đơn Lưu] => edit [hóa đơn xuất]
    /// </summary>
    class editExportOrderViewModel
    {
        
        Customer customer;
        bool _isSaved = false;
        USER user = new USER();
        bool _isChanged = false;
        ORDER order = new ORDER();
        PaymentInfomation payment;
        /// <summary>
        /// Property xác Hóa đơn = [định Đá Hoa Cương]
        /// - Được dùng ở lớp CodeBehide của giao diện sử dụng ViewModel này. Mục đích ẩn hiện 3 cột liên quan
        /// </summary>
        public bool IsMarcle { get; set; }
        StoreInfomation storeInfo = new StoreInfomation();
        ObservableCollection<Products> obsProducts = new ObservableCollection<Products>();
        ObservableCollection<Products> listProducts = new ObservableCollection<Products>();
        ObservableCollection<Products> newListProducts = new ObservableCollection<Products>();

    #region --- get; set; ---
        public USER User
        {
            get { return user; }
            set { user = value; }
        }       
        public ORDER Order
        {
            get { return order; }
            set { order = value; }
        }
        public bool IsSaved
        {
            get { return _isSaved; }
            set { _isSaved = value;}
        }
        public bool IsChanged
        {
            get { return _isChanged; }
            set { _isChanged = value; }
        }
        public Customer Customer
        {
            get { return customer; }
            set { customer = value; }
        }
        public PaymentInfomation Payment
        {
            get { return payment; }
            set { payment = value; }
        }
        public StoreInfomation StoreInfo
        {
            get { return storeInfo; }
            set { storeInfo = value; }
        }
        public ICommand SaveOrderCommand { get; set; }
        public ICommand PrintOrderCommand { get; set; }
        public ObservableCollection<Products> ObsProducts
        {
            get { return obsProducts; }
            set { obsProducts = value; }
        }
        public ObservableCollection<Products> ListProducts
        {
            get { return listProducts; }
            set { listProducts = value; }
        }
        public ObservableCollection<Products> NewListProducts
        {
            get { return newListProducts; }
            set { newListProducts = value; }
        }
    #endregion
        
        public editExportOrderViewModel(int orderID)
        {
            getOrderDetail(orderID);
            getListProducts();
            initializeCommand();
        }

        private void getOrderDetail(int iOrderID)
        {
            Order = WPFServices.Services.Orders.GetOrderByID(iOrderID);
            IsMarcle = Order.ORDER_TYPES == 1 ? true : false;
            try
            {
                var list = WPFServices.Services.OrderDetails.GetListByOrderID(iOrderID).Select(
                    x => new Products()
                    {
                        ProductIdAuto = x.PRODUCT.ID_PRO_AUTO,
                        ProductId = x.PRODUCT.ID_PRO,
                        ProductName = x.PRODUCT.NAME_PRO,
                        ProductDescription = x.PRODUCT.DESCRIPTIONS,
                        InventoryCount = x.QUANTITY.Value,

                        // thêm mới ngày 10/5 để thêm chức năng Đá hoa cương
                        ProductHeight = x.HEIGHT?? 0,
                        ProductWidth = x.WIDTH ?? 0,
                        ProductM2 = x.M2 ?? 0,
                        IsMarble = IsMarcle,

                        SellPrice = x.PRODUCT.DETAILS_PRODUCTS.SELL_PRICE.Value, // biến này phải được set trước biến Price để thực thi việc hiện giá đúng (khi thực thi Property Set của SellPrice => thực thi Price)
                        CostPrice = x.PRODUCT.DETAILS_PRODUCTS.COST_PRICES.Value,
                        IsCostPrice = x.ACTIVEPRICE.Value, // phải bỏ sau SellPrice vì trong SellPrice có statement gán  IsCostPrice = false;
                        Price = x.ACTIVEPRICE.Value ? x.PRODUCT.DETAILS_PRODUCTS.COST_PRICES.Value : x.PRODUCT.DETAILS_PRODUCTS.SELL_PRICE.Value,

                        UnitName = x.PRODUCT.DETAILS_PRODUCTS.UNIT.NAME_UNIT,
                        CatalogName = x.PRODUCT.CATALOG.NAME_CATALOG

                    });
            
            foreach (Products pro in list)
                ListProducts.Add(pro);
            }
            catch (Exception ex)
            {
                throw new Exception("Lỗi lấy thông tin hóa đơn \n"+ex.Message);
            }

            
            User.ID_USER = Order.ID_USER;
            Customer = new Customer()
            {
                IdCus = Order.ID_CUS,
                CusName = Order.CUSTOMER.NAME_CUS,
                Address = Order.CUSTOMER.ADDRESS,
                Phone = Order.CUSTOMER.PHONES
            };

            Payment = new PaymentInfomation()
            {
                OldDebts = Order.OLD_DEBTS.Value,
                PrePaid = Order.PRE_PAID.Value,
                Remain = Order.TOTAL.Value - Order.PRE_PAID.Value,
                TotalPayment = Order.TOTAL.Value,
                SumOut = Order.TOTAL.Value - Order.OLD_DEBTS.Value
            };
        }

        private void getListProducts()
        {
            var listProducts = WPFServices.Services.Products.GetListProducts().Select(
                x => new Products
                {
                    ProductIdAuto = x.ID_PRO_AUTO,
                    ProductId = x.ID_PRO,
                    ProductName = x.NAME_PRO,
                    ProductDescription = x.DESCRIPTIONS,
                    InventoryCount = (int)x.DETAILS_PRODUCTS.INVENTORY_COUNT,
                    CostPrice = (decimal)x.DETAILS_PRODUCTS.COST_PRICES,
                    Unit = new Unit { UnitID = x.DETAILS_PRODUCTS.UNIT.ID_UNIT, UnitName = x.DETAILS_PRODUCTS.UNIT.NAME_UNIT, UnitNote = x.DETAILS_PRODUCTS.UNIT.NOTES_UNIT },
                    catalog = new Catalogs { CatalogName = x.CATALOG.NAME_CATALOG, CatalogNotes = x.CATALOG.NOTES_CATALOG, IDCatalog = x.CATALOG.ID_CATALOG }
                });
            foreach (Products p in listProducts)
                obsProducts.Add(p);
            ListProducts.Add(new Products());
        }

        public void saveOrder(object o) // object o => khớp với command
        {
            try
            {
                Order.OLD_DEBTS = Payment.OldDebts;
                Order.PRE_PAID = Payment.PrePaid;
                Order.TOTAL = Payment.TotalPayment;
                Order.ID_USER = User.ID_USER??0;
                var cus = new CUSTOMER()
                {
                    ID_CUS = Customer.IdCus,
                    NAME_CUS = Customer.CusName,
                    ADDRESS = Customer.Address,
                    PHONES = Customer.Phone
                };

                List<ORDER_DETAILS> orDetailLists = new List<ORDER_DETAILS>();
                foreach (Products pro in ListProducts)
                {
                    ORDER_DETAILS ord = new ORDER_DETAILS()
                    {

                        ID_ORD = Order.ID_ORD,
                        ID_PRO_AUTO = pro.ProductIdAuto,
                        QUANTITY = pro.InventoryCount,
                        ACTIVEPRICE = pro.IsCostPrice,
                        HEIGHT = pro.ProductHeight,
                        WIDTH = pro.ProductWidth,
                        M2 = pro.ProductM2
                    };
                    orDetailLists.Add(ord);
                }

                WPFServices.Services.Orders.UpdateOrder(Order);
                WPFServices.Services.CustomersService.UpdateCustomer(cus);
                WPFServices.Services.OrderDetails.UpdateOrderDetail(orDetailLists, true, IsMarcle);
                IsSaved = true;
                IsChanged = false;
                NewListProducts = new ObservableCollection<Products>();
                MessageBox.Show("Cập nhật thành công!");
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        /// <summary>
        /// ham kiểm tra trong danh sách thêm mới có chứa product hay k
        /// </summary>
        /// <returns></returns>
        public bool isExistProduct()
        {
            if (IsChanged)
                return true;
            foreach (Products pro in NewListProducts)
                if (pro.ProductIdAuto > 0 && pro.InventoryCount > 0)
                    return true;
            return false;
        }

        public bool isInNewListProduct(Products pro)
        {
            foreach (Products _pro in NewListProducts)
                if (_pro.ProductIdAuto == pro.ProductIdAuto)
                    return true;
            return false;
        }

        public void addNewProduct()
        {
            Products pro = new Products();
            IsSaved = false;
            //IsChanged = true;
            ListProducts.Add(pro);
            NewListProducts.Add(pro);
        }

        public ObservableCollection<Products> removeAllNullProduct()
        {
            ObservableCollection<Products> newList = new ObservableCollection<Products>();
            foreach (Products pro in ListProducts)
                if (pro.ProductIdAuto > 0)
                    newList.Add(pro);
            return newList;
        }

        public void CaculationPaymentForAllProduct()
        {
            try
            {
                Payment.SumOut = 0;
                foreach (var pro in ListProducts.Where(pro => !string.IsNullOrEmpty(pro.ProductId)))
                    Payment.SumOut += pro.TotalOutPayment;
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
        }

       
    #region --- Command ---

        private void initializeCommand()
        {
            SaveOrderCommand = new RelayCommand<object>
                (
                    canExcutedSaveFunction,
                    saveOrder
                );
            PrintOrderCommand = new RelayCommand<object>
                (
                    canExcutedPrintCommand,
                    printOrder
                );
        }

        private bool canExcutedPrintCommand(object obj)
        {
            return IsSaved;
        }

        public void printOrder(object o)
        {
            IDictionary<string, string> param = new Dictionary<string, string>();
            param.Add("StoreName", StoreInfo.StoreName);
            param.Add("Address", StoreInfo.Address);
            param.Add("Mobile", StoreInfo.Mobile);
            param.Add("Phone", StoreInfo.Phone);

            //tạm thời cho parameter cuối là false đại diện cho hóa đơn thường : edited
            var cryRep = new FormCryReOutInvetory(removeAllNullProduct(), User, Customer, Payment, Order.DATE_ORD.Value, param, IsMarcle);
            cryRep.ShowDialog();
        }

        public bool canExcutedSaveFunction(object obj)
        {
            if (string.IsNullOrEmpty(User.ID_USER.ToString()) || WPFServices.Services.UserService.GetUser(User.ID_USER??0) == null || !isExistProduct() || !IsChanged)
                return false;
            return true;
        }

    #endregion
    }

    public class StoreInfomation:PropertyChangedBase
    {
        string storeName;
        string phone;
        string address;
        string mobile;

        public StoreInfomation()
        { 
            StoreName = "KHANG HUY";
            Address = "667 CMT8, KP2, Thị Xã Tây Ninh";
            Phone = "(066)2220333";
            Mobile = "0982777728";
        }


        public string StoreName
        {
            get { return storeName; }
            set { storeName = value; OnPropertyChanged("StroreName"); }
        }

        public string Address
        {
            get { return address; }
            set { address = value; OnPropertyChanged("Address"); }
        }

        public string Mobile
        {
            get { return mobile; }
            set { mobile = value; OnPropertyChanged("Mobile"); }
        }

        public string Phone
        {
            get { return phone; }
            set { phone = value; OnPropertyChanged("Phone"); }
        }
            
    }
}
